/*
 * Copyright (c) 2022 Hong Jiahua
 * https://gitee.com/arrco/jh_static_set
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef __JH_STATIC_SET_H__
#define __JH_STATIC_SET_H__

/**
  * @brief  集合数据结构
  */
//结点使用的数据类型
typedef unsigned short jh_static_set_node_type;

typedef struct jh_static_set_node{
    jh_static_set_node_type height;
    jh_static_set_node_type parent;
    jh_static_set_node_type left;
    jh_static_set_node_type right;
} jh_static_set_node_t;

typedef struct {
    jh_static_set_node_type root;
    size_t count;
    int (*compare)(const void*, const void*);
    
    void* base;
    size_t num;
    size_t size;
    size_t offset;
    size_t datasize;
    size_t dataoffset;
} jh_static_set_t;

#define JH_STATIC_SET_OFFSETOF(__type, __member) ((size_t)&((__type *)0)->__member)

/**
  * @brief  集合数据迭代
  */
#define JH_STATIC_SET_ITER(__set, __node, __value)    \
    for(int __jh_i = __node ? (jh_static_set_memcpy(__set, __node, __value), 0) : -1;\
            __jh_i == 0; __jh_i = jh_static_set_find_next_value(__set, &(__node), __value))
/**
  * @brief  集合数据反向迭代
  */
#define JH_STATIC_SET_ITER_REVERSE(__set, __node, __value)    \
    for(int __jh_i = __node ? (jh_static_set_memcpy(__set, __node, __value), 0) : -1;\
            __jh_i == 0; __jh_i = jh_static_set_find_prve_value(__set, &(__node), __value))

/*从集合的节点中获取数据*/
void jh_static_set_memcpy(jh_static_set_t* set, jh_static_set_node_type usernode, void* value);
/*在集合中查找下一个数据*/
int jh_static_set_find_next_value(jh_static_set_t* set, jh_static_set_node_type* usernode, void* value);
/*在集合中查找上一个数据*/
int jh_static_set_find_prve_value(jh_static_set_t* set, jh_static_set_node_type* usernode, void* value);

/*在集合中查找第一个大于或等于value数值的数据节点*/
jh_static_set_node_type jh_static_set_lower_bound(jh_static_set_t* set, void* value);
/*在集合中查找第一个大于value数值的数据节点*/
jh_static_set_node_type jh_static_set_upper_bound(jh_static_set_t* set, void* value);
/*在集合中查找第一个数据节点*/
jh_static_set_node_type jh_static_set_begin(jh_static_set_t* set);
/*在集合中查找最后一个数据节点*/
jh_static_set_node_type jh_static_set_end(jh_static_set_t* set);
/*获取集合的数据数量*/
size_t jh_static_set_count(jh_static_set_t* set);
/*判断集合是否为空*/
int jh_static_set_is_empty(jh_static_set_t* set);
/*判断集合是否已满*/
int jh_static_set_is_full(jh_static_set_t* set);
/*在集合中查找数据*/
jh_static_set_node_type jh_static_set_find(jh_static_set_t* set, void* value);
/*在集合中插入数据*/
int jh_static_set_insert(jh_static_set_t* set, void* value);
/*删除集合中的数据*/
int jh_static_set_erase(jh_static_set_t* set, void* value);
/*清空集合*/
int jh_static_set_clear(jh_static_set_t* set);
/*集合初始化*/
int jh_static_set_init(jh_static_set_t* set, void* base, size_t num, size_t size, size_t offset, size_t datasize, size_t dataoffset, int (*compare)(const void*, const void*));

#endif